/**
 * user 权限控制
 */
const jwt = require('jsonwebtoken');
const {NEED_LOGIN, SSO_ERROR, ILLEGAL_OPERATION} = require('../ErrorInfo');

// 白名单
const white_list = [
  '/api/user/login'
];

module.exports = async (ctx, next) => {
  // 该中间件只会对 admin/ 下的路由进行检验
  if (ctx.path.startsWith('/api/user')) {
    // 在白名单里的路由直接放行
    if (white_list.includes(ctx.path)) {
      await next();
      return;
    }

    let token;
    if(!ctx.decoded){
      // 下面的路由都是需要带上 authorization头 才能允许访问的
      const authorization = ctx.get('authorization');
      if (!authorization) return helper.fail(NEED_LOGIN);
      token = ctx.header.authorization.split(' ')[1];

      // 检验token是否合法和是否过期
      try {
        ctx.decoded = jwt.verify(token, config.jwt.secret);
      } catch (e) {
        return helper.fail(NEED_LOGIN);
      }
    }

    if(!ctx.decoded.isUser) return helper.fail(ILLEGAL_OPERATION); // 非法操作 这里应该记录IP ...

    const userid = ctx.decoded.userid;
    const rToken = await helper.redis.get(`user:token:${userid}`);

    // 已经logout
    if (!rToken) { // redis中不存在userid对应的token 说明已经登出了 此token作废
      return helper.fail(NEED_LOGIN);
    }

    // SSO单点登录验证(如果开启了的话)
    // token有效且没有过期没有logout 但 和redis里存的不一样 说明生成了新的token(用其它电脑登录了)
    if (rToken !== token && config.SSO) {
      return helper.fail(SSO_ERROR);
    }

    // 权限验证通过
    await next();
  }
  await next();
};
